package com.spring.aop;

import com.spring.aop.interceptor.Interceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 拦截器链 对象
 */
public class InterceptorChain {
	// 保存某个方法的所有拦截器
	private final List<Interceptor> interceptors = new ArrayList<>();
	
	// 执行深度，完成方法时记得重置回-1，否则下次拦截器就会失效掉
	private int index = -1;
	
	// todo 多线程改造，并发请求的话， index 会乱掉
	//private ThreadLocal<Integer> index = new ThreadLocal<>();
	
	
	public InterceptorChain(List<Interceptor> interceptors) {
		this.interceptors.addAll(interceptors);
	}
	
	// 添加拦截器
	public void addInterceptors(List<Interceptor> interceptors) {
		this.interceptors.addAll(interceptors);
	}
	
	
	/**
	 * 核心处理方法, 每个拦截器上的方法 都会调用 链的 proceed() 方法
	 */
	public Object proceed(Object targetObject, Method targetMethod, Object[] args) throws Throwable {
		if (index == interceptors.size() - 1) {
			// 说明拦截器已经走完了，可以调用目标方法了
			// 重置index
			index = -1;
			// 这里应该调用并返回目标方法
			return targetMethod.invoke(targetObject, args);
		}
		// 还没有到目标方法哪里，说明还在拦截器链中
		Interceptor interceptor = interceptors.get(++index);
		return interceptor.invoke(this, targetObject, targetMethod, args);
	}
}
